package com.tbit.main.service.impl;

import com.tbit.main.constant.*;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.tbit.main.constant.RedisConstant.PHOTO;

/**
 * @author LMY
 * @create 2021-12-27 15:47
 * 站点设备定时任务
 */
@Service("parkPointDeviceQuartzService")
public class ParkPointDeviceQuartzServiceImpl implements ParkPointDeviceQuartzService {

    @Autowired
    private ParkPointBoundAbnormalService parkPointBoundAbnormalService;
    @Autowired
    private BleBeaconService bleBeaconService;
    @Autowired
    private ParkPointBoundService parkPointBoundService;
    @Autowired
    private DataService dataService;
    @Autowired
    private AccountConfigExtService accountConfigExtService;
    @Autowired
    private CameraService cameraService;
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private MachineAbnormalService machineAbnormalService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private RuleRidePhotoLogService ruleRidePhotoLogService;
    @Autowired
    private AccountConfigService accountConfigService;
    @Autowired
    private RedisService redisService;

    @Override
    //@Scheduled(cron = "0 1/6 * * * ?")
    public void bleBeacon() {

        LogUtil.info("道钉异常定时任务");
        long t1 = System.currentTimeMillis();

        /**查找系统异常*/
        List<ParkPointBoundAbnormal> parkPointBoundAbnormals = parkPointBoundAbnormalService.getByTypeState(ParkPointBoundConstant.type_ble, ParkPointBoundConstant.state_abnormal_s);
        Map<Integer, List<String>> mapMachineNO = new LinkedHashMap<>();

        if (parkPointBoundAbnormals != null && parkPointBoundAbnormals.size() > 0) {

            for (ParkPointBoundAbnormal parkPointBoundAbnormal : parkPointBoundAbnormals) {
                if (mapMachineNO.containsKey(parkPointBoundAbnormal.getAccountId())) {
                    mapMachineNO.get(parkPointBoundAbnormal.getAccountId()).add(parkPointBoundAbnormal.getMachineNO());
                } else {
                    List<String> machineNOAccountIds = new LinkedList<>();
                    machineNOAccountIds.add(parkPointBoundAbnormal.getMachineNO());
                    mapMachineNO.put(parkPointBoundAbnormal.getAccountId(), machineNOAccountIds);
                }
            }

            for (Integer accountId : mapMachineNO.keySet()) {

                AccountConfigExt accountConfigExt = dataService.getAccountidExt(accountId + AccountConfigExtConstant.ble);
                if (accountConfigExt != null) {
                    /**回复正常*/
                    List<BleBeacon> bleBeacons = bleBeaconService.getByNOTime(mapMachineNO.get(accountId), DateTimeUtil.getDayAgoTime(Integer.valueOf(accountConfigExt.getParamValue())));

                    if (bleBeacons != null && bleBeacons.size() > 0) {
                        parkPointBoundAbnormalService.delBatch(bleBeacons.stream().map(BleBeacon::getMachineNO).collect(Collectors.toList()));
                        bleBeaconService.updateState(bleBeacons.stream().map(BleBeacon::getMachineNO).collect(Collectors.toList()), ParkPointBoundConstant.state_normal);
                    }
                }
            }

        }

        /**获取所有配置*/
        List<AccountConfigExt> accountConfigExts = accountConfigExtService.getAll();
        for (AccountConfigExt accountConfigExt : accountConfigExts) {
            if (accountConfigExt.getParamKey().equals(AccountConfigExtConstant.ble)) {
                /**新增异常*/
                List<BleBeacon> bleBeaconList = bleBeaconService.getTime(DateTimeUtil.getDayAgoTime(Integer.valueOf(accountConfigExt.getParamValue())), null,
                        ParkPointBoundConstant.state_normal, accountConfigExt.getAccountId());
                if (bleBeaconList != null && bleBeaconList.size() > 0) {

                    List<String> abnormalList = bleBeaconList.stream().map(BleBeacon::getMachineNO).collect(Collectors.toList());

                    if (mapMachineNO.get(accountConfigExt.getAccountId()) != null && mapMachineNO.get(accountConfigExt.getAccountId()).size() > 0) {
                        abnormalList = ListUtil.getSameString(abnormalList, mapMachineNO.get(accountConfigExt.getAccountId()));
                    }
                    if (abnormalList != null && abnormalList.size() > 0) {
                        parkPointBoundAbnormalService.addBatch(abnormalList, ParkPointBoundConstant.type_ble, ParkPointBoundConstant.state_abnormal_s, DateTimeUtil.getNowTime(), null, accountConfigExt.getAccountId());
                        bleBeaconService.updateState(abnormalList, ParkPointBoundConstant.state_abnormal_s);
                    }
                }
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("道钉异常定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "0 1/4 * * * ?")
    public void rfid() {

        LogUtil.info("rfid异常定时任务");
        long t1 = System.currentTimeMillis();

        /**查找系统异常*/
        List<ParkPointBoundAbnormal> parkPointBoundAbnormals = parkPointBoundAbnormalService.getByTypeState(ParkPointBoundConstant.type_rfid, ParkPointBoundConstant.state_abnormal_s);

        Map<Integer, List<String>> mapMachineNO = new LinkedHashMap<>();
        if (parkPointBoundAbnormals != null && parkPointBoundAbnormals.size() > 0) {

            for (ParkPointBoundAbnormal parkPointBoundAbnormal : parkPointBoundAbnormals) {
                if (mapMachineNO.containsKey(parkPointBoundAbnormal.getAccountId())) {
                    mapMachineNO.get(parkPointBoundAbnormal.getAccountId()).add(parkPointBoundAbnormal.getMachineNO());
                } else {
                    List<String> machineNOAccountIds = new LinkedList<>();
                    machineNOAccountIds.add(parkPointBoundAbnormal.getMachineNO());
                    mapMachineNO.put(parkPointBoundAbnormal.getAccountId(), machineNOAccountIds);
                }
            }

            for (Integer accountId : mapMachineNO.keySet()) {

                AccountConfigExt accountConfigExt = dataService.getAccountidExt(accountId + AccountConfigExtConstant.rfid);
                if (accountConfigExt != null) {
                    /**回复正常*/
                    List<ParkPointBound> parkPointBounds = parkPointBoundService.getByNOTime(mapMachineNO.get(accountId), DateTimeUtil.getDayAgoTime(Integer.valueOf(accountConfigExt.getParamValue())));

                    if (parkPointBounds != null && parkPointBounds.size() > 0) {
                        parkPointBoundAbnormalService.delBatch(parkPointBounds.stream().map(ParkPointBound::getMachineNO).collect(Collectors.toList()));
                        parkPointBoundService.updateState(parkPointBounds.stream().map(ParkPointBound::getMachineNO).collect(Collectors.toList()), ParkPointBoundConstant.state_normal);
                    }
                }
            }
        }


        /**获取所有配置*/
        List<AccountConfigExt> accountConfigExts = accountConfigExtService.getAll();
        for (AccountConfigExt accountConfigExt : accountConfigExts) {
            if (accountConfigExt.getParamKey().equals(AccountConfigExtConstant.rfid)) {
                /**新增异常*/
                List<ParkPointBound> parkPointBoundsList = parkPointBoundService.getTime(DateTimeUtil.getDayAgoTime(Integer.valueOf(accountConfigExt.getParamValue())),
                        null, null, ParkPointBoundConstant.state_normal, accountConfigExt.getAccountId());
                if (parkPointBoundsList != null && parkPointBoundsList.size() > 0) {

                    List<String> abnormalList = parkPointBoundsList.stream().map(ParkPointBound::getMachineNO).collect(Collectors.toList());

                    if (mapMachineNO.get(accountConfigExt.getAccountId()) != null && mapMachineNO.get(accountConfigExt.getAccountId()).size() > 0) {
                        abnormalList = ListUtil.getSameString(abnormalList, mapMachineNO.get(accountConfigExt.getAccountId()));
                    }
                    if (abnormalList != null && abnormalList.size() > 0) {
                        parkPointBoundAbnormalService.addBatch(abnormalList, ParkPointBoundConstant.type_rfid, ParkPointBoundConstant.state_abnormal_s, DateTimeUtil.getNowTime(), null, accountConfigExt.getAccountId());
                        parkPointBoundService.updateState(abnormalList, ParkPointBoundConstant.state_abnormal_s);
                    }
                }
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("rfid异常定时任务时间" + (t2 - t1) + "ms");
    }

    /**
     * 摄像头自动拍照
     */
    @Override
    //@Scheduled(cron = "0 1/30 * * * ?")
    public void cameraOrder() {

        LogUtil.info("摄像头指令定时任务");
        long t1 = System.currentTimeMillis();

        List<AccountConfig> accountConfigs = accountConfigService.getAll();
        String remark = "系统自动下发拍照指令";

        List<String> machineNOs = cameraService.getNotExist();
        if (machineNOs != null && machineNOs.size() > 0) {
            cameraService.deleteS(machineNOs);
        }

        for (AccountConfig accountConfig : accountConfigs) {

            /**系统自动下发拍照*/
            if (accountConfig.getPhotoTime() != null && accountConfig.getPhotoTime() != 0) {

                List<Camera> cameras = cameraService.getAccountIdTime(accountConfig.getAccountId(), DateTimeUtil.getHoursAgo(accountConfig.getPhotoTime()));
                if (cameras != null && cameras.size() > 0) {
                    String paramName = ControlTypeConstant.PHOTO_0;

                    for (Camera camera : cameras) {
                        try {
                            String serNO = UUID.randomUUID().toString();
                            terControlService.sendControl(serNO, camera.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_PHOTO, paramName, "");

                            redisService.add(PHOTO + serNO, camera.getMachineNO(), 60);
                            Integer machineId = dataService.getMachineId(camera.getMachineNO());
                            Machine machine = dataService.getMachine(machineId);
                            /**远程指令日志*/
                            OrderLog orderLog = new OrderLog();
                            orderLog.setMachineId(machine.getMachineId());
                            orderLog.setMachineNo(machine.getMachineNO());
                            orderLog.setUserCode(machine.getUserCode());
                            orderLog.setOpType(0);
                            orderLog.setOpId(0);
                            orderLog.setAccountUserId(0);
                            orderLog.setOpTime(DateTimeUtil.getNowTime());
                            orderLog.setChannelType(0);
                            orderLog.setBusinessType(1);
                            orderLog.setOrderType(ControlTypeConstant.CONTROL_TYPE_PHOTO);
                            orderLog.setOrderSerNo(serNO);
                            orderLog.setOrderSource(8);
                            orderLog.setOrderContent(ControlTypeConstant.CONTROL_TYPE_PHOTO);
                            orderLog.setRemark(remark);
                            orderLogService.insert(orderLog);
                        } catch (Exception e) {
                            LogUtil.info(e.getMessage());
                        }

                    }
                }
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("摄像头指令定时任务时间" + (t2 - t1) + "ms");
    }

    /**
     * 摄像头异常
     */
    @Override
    //@Scheduled(cron = "0 1/10 * * * ?")
    public void cameraAbnormal() {

        LogUtil.info("摄像头异常定时任务");
        long t1 = System.currentTimeMillis();

        List<AccountConfig> accountConfigs = accountConfigService.getAll();
        for (AccountConfig accountConfig : accountConfigs) {

            /**系统自动判断异常*/
            if (accountConfig.getPhotoAbnormal() != null && accountConfig.getPhotoAbnormal() != 0) {

                /**加载摄像头异常设备id*/
                List<MachineAbnormal> abnormalMachines = machineAbnormalService.getAccountIdType(MachineAbnormalConstant.MACHINE_ABNORMAL_SXT, accountConfig.getAccountId());
                if (abnormalMachines != null && abnormalMachines.size() > 0) {
                    List<String> machineNOs = abnormalMachines.stream().map(MachineAbnormal::getMachineNO).collect(Collectors.toList());

                    /**查询摄像头正常设备*/
                    List<String> MachineNOs = cameraService.getMachineNOsTime(machineNOs, DateTimeUtil.getHoursAgo(accountConfig.getPhotoAbnormal()));
                    MachineNOs = MachineNOs.stream().filter(e -> e != null).collect(Collectors.toList());
                    /**摄像头异常解除*/
                    if (MachineNOs != null && MachineNOs.size() > 0) {
                        List<Integer> machineIds = machineService.getMachineIdByNOs(MachineNOs, null);
                        machineAbnormalService.deleteBatch(machineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_SXT);
                    }
                }

                /**加载所有最后上报时间大于30分钟数据 */
                List<Camera> terMachineNO30 = cameraService.getAccountIdTime(accountConfig.getAccountId(), DateTimeUtil.getHoursAgo(accountConfig.getPhotoAbnormal()));
                List<String> terMachineNO30s = terMachineNO30.stream().map(Camera::getMachineNO).collect(Collectors.toList());
                if (terMachineNO30s != null && terMachineNO30s.size() > 0) {
                    /**获取到设备id*/
                    List<Integer> machineId30s = dataService.getByMachineIds(terMachineNO30s);
                    /**获取新增的摄像头异常车辆*/
                    List<Integer> abnormalMachineIds = abnormalMachines.stream().map(MachineAbnormal::getMachineId).collect(Collectors.toList());
                    List<Integer> newAbnormalMachineIds = ListUtil.getSameIntegerList(machineId30s, abnormalMachineIds);
                    newAbnormalMachineIds = newAbnormalMachineIds.stream().filter(e -> e != null).collect(Collectors.toList());
                    /**批量新增*/
                    if (newAbnormalMachineIds != null && newAbnormalMachineIds.size() > 0) {
                        machineAbnormalService.insertBatch(newAbnormalMachineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_SXT, DateTimeUtil.getNowTime());
                    }
                }
            } else {
                machineAbnormalService.delAccountId(accountConfig.getAccountId(), MachineAbnormalConstant.MACHINE_ABNORMAL_SXT);
            }
        }


        long t2 = System.currentTimeMillis();
        LogUtil.info("摄像头异常定时任务时间" + (t2 - t1) + "ms");
    }

    /**
     * 删除过期图片
     */
    @Override
    // @Scheduled(cron = "0 1/30 * * * ?")
    public void cameraDel() {

        LogUtil.info("删除过期摄像头图片定时任务");
        long t1 = System.currentTimeMillis();

        List<RuleRidePhotoLog> ruleRidePhotoLogLis = ruleRidePhotoLogService.getTime(DateTimeUtil.getMinsAgo(30));
        for (RuleRidePhotoLog ruleRidePhotoLog : ruleRidePhotoLogLis) {
            if (ruleRidePhotoLog.getFtpUrl() != null && !ruleRidePhotoLog.getFtpUrl().equals("")) {

                /**阿里云配置*/
                OssConfig ossConfig = new OssConfig(AliOssConstant.endpoint, AliOssConstant.accessKeyId, AliOssConstant.accessKeySecret,
                        AliOssConstant.bucketName);

                String fileName = ruleRidePhotoLog.getFtpUrl().substring(ruleRidePhotoLog.getFtpUrl().lastIndexOf("/") + 1);

                OssFileUtils.del(ossConfig, fileName);


                FtpUtils.deleteFile(FtpConfig.ftpUrl, FtpConfig.username, FtpConfig.password, FtpConfig.port, ruleRidePhotoLog.getFtpUrl(), fileName);
            }
            ruleRidePhotoLogService.delete(ruleRidePhotoLog.getPhotoId());
        }


        long t2 = System.currentTimeMillis();
        LogUtil.info("删除过期摄像头图片定时任务时间" + (t2 - t1) + "ms");
    }
}
